package com.joolun.weixin.config;

import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Maps;
import com.joolun.common.config.ScrmConfig;
import com.joolun.common.constant.Constants;
import com.joolun.common.corp.TenantContext;
import com.joolun.system.domain.SysCorpConfig;
import com.joolun.system.service.impl.SysCorpConfigServiceImpl;
import com.joolun.weixin.handler.CpAbstractHandler;
import com.joolun.weixin.handler.CpLogHandler;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @author ：qiuzl
 * @date ：Created in 2021/12/12 20:57
 * @description：继承ScrmConfig是为了让ScrmConfig先初始化
 **/
@Slf4j
@Component
public class WxCpConfiguration extends ScrmConfig {

    @Autowired
    private CpLogHandler logHandler;

    @Autowired
    private Map<String, CpAbstractHandler> eventHandlerMap;

    @Autowired
    private SysCorpConfigServiceImpl sysCorpConfigService;

    @Value("${baseApiUrl}")
    private volatile static String baseApiUrl;

    private static Map<String, WxCpService> cpServiceMap = Maps.newHashMap();

    private static Map<String, WxCpMessageRouter> routers = Maps.newHashMap();

    public static Map<String, WxCpMessageRouter> getRouters() {
        return routers;
    }

    private static WxCpService getBySecret(String corpId, Integer mainAgentID, String secret, String token, String aseKey) {
        if (cpServiceMap.containsKey(secret)) {
            return cpServiceMap.get(secret);
        } else {
//            WxCpMemoryConfigStorage configStorage = new WxCpMemoryConfigStorage();
//            log.info(JSONObject.toJSONString(configStorage));
//            configStorage.setCorpId(ScrmConfig.getExtCorpID());
//            configStorage.setAgentId(mainAgentID);
//            configStorage.setCorpSecret(secret);
//            configStorage.setToken(token);
//            configStorage.setAesKey(aseKey);
//            configStorage.setBaseApiUrl(baseApiUrl);
            WxCpService wxCpService = new WxCpServiceImpl();
//            log.info(JSONObject.toJSONString(configStorage));
            WxCpDefaultConfigImpl configStorage = new WxCpDefaultConfigImpl();
            configStorage.setCorpId(corpId);
            configStorage.setAgentId(mainAgentID);
            configStorage.setCorpSecret(secret);
            configStorage.setToken(token);
            configStorage.setAesKey(aseKey);
//            configStorage.setAgentId(ScrmConfig.getMainAgentID());
//            configStorage.setCorpSecret(ScrmConfig.getCustomerSecret());
//            configStorage.setToken(ScrmConfig.getShortCallbackToken());
//            configStorage.setAesKey(ScrmConfig.getCustomerAesKey());
            configStorage.setBaseApiUrl(ScrmConfig.getBaseApiUrl());
            log.info(ScrmConfig.getBaseApiUrl() + "==================================================");
            log.info(configStorage.getApiUrl("/test")+"==================================================");
            //log.info(JSONObject.toJSONString(configStorage)+"==================================================");
            wxCpService.setWxCpConfigStorage(configStorage);
            cpServiceMap.put(secret, wxCpService);
            return wxCpService;
        }
    }

//    public static WxCpService getWxCpService(Integer agentId, String secret) {
//        return getBySecret(agentId, secret, null, ScrmConfig.getCallbackAesKey());
//    }
    //
    public static  WxCpService getWxCpService(SysCorpConfig sysCorpConfig) {
        // 原：读取yml本地配置
        //ScrmConfig.getMainAgentID()  ScrmConfig.getMainAgentSecret()  ScrmConfig.getCallbackAesKey()
        // 新：读取数据库动态配置
        return getBySecret(sysCorpConfig.getCorpId(),Integer.parseInt(sysCorpConfig.getMainAgentId()), sysCorpConfig.getMainAgentSecret(), null, sysCorpConfig.getCallbackAesKey());
    }
    // 企微部门、客户
    public static WxCpService getAddressBookWxCpService(SysCorpConfig sysCorpConfig) {
        //ScrmConfig.getMainAgentID()  ScrmConfig.getContactSecret() ScrmConfig.getCallbackToken(), ScrmConfig.getCallbackAesKey()
        return getBySecret(sysCorpConfig.getCorpId(),Integer.parseInt(sysCorpConfig.getMainAgentId()), sysCorpConfig.getContactSecret(), sysCorpConfig.getCallbackToken(), sysCorpConfig.getCallbackAesKey());
    }
    // 企微群聊、获客链接
    public static WxCpService getCustomerSecretWxCpService(SysCorpConfig sysCorpConfig) {
        //ScrmConfig.getMainAgentID()  ScrmConfig.getCustomerSecret() ScrmConfig.getShortCallbackToken(), ScrmConfig.getCustomerAesKey()
        return getBySecret(sysCorpConfig.getCorpId(),Integer.parseInt(sysCorpConfig.getMainAgentId()), sysCorpConfig.getCustomerSecret(), sysCorpConfig.getShortCallbackToken(), sysCorpConfig.getCustomerAesKey());
    }

    /**
     * 初始化所有主体配置信息
     */
    @PostConstruct
    public void initServices() {
        System.out.println("开始初始化多主体配置......................");
        try {
            // 从数据库获取所有启用的企业配置
            List<SysCorpConfig> configList = sysCorpConfigService.selectSysCorpConfigList();

            if (configList.isEmpty()) {
                System.err.println("警告: 未找到任何企业配置!");
                return;
            }
            // 为每个配置创建服务和路由器
            for (SysCorpConfig config : configList) {
                try {
                    initCorpService(config);
                } catch (Exception e) {
                    System.err.printf("初始化企业[%s]失败: %s%n", config.getCorpId(), e.getMessage());
                    e.printStackTrace();
                }
            }
            System.out.printf("成功初始化%d个企业配置%n", configList.size());
        } catch (Exception e) {
            System.err.println("初始化多主体配置失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * 初始化单个主体配置信息
     */
    public void initCorpService(SysCorpConfig config) {
        System.out.printf("初始化企业配置: corpId=%s, agentId=%s",
                config.getCorpId(), config.getMainAgentId());
        val configStorage = new WxCpDefaultConfigImpl();
        configStorage.setCorpId(config.getCorpId());
        configStorage.setAgentId(Integer.parseInt(config.getMainAgentId()));
        configStorage.setCorpSecret(config.getCustomerSecret());
        configStorage.setToken(config.getShortCallbackToken());
        configStorage.setAesKey(config.getCustomerAesKey());
        configStorage.setBaseApiUrl(baseApiUrl);
        val service = new WxCpServiceImpl();
        service.setWxCpConfigStorage(configStorage);
        routers.put(config.getCorpId(), this.newRouter(service));
    }

    private WxCpMessageRouter newRouter(WxCpService wxCpService) {
        final val newRouter = new WxCpMessageRouter(wxCpService);

        //事件业务处理
        Constants.WX_ALL_EVENT_TYPES.forEach(eventType -> {
            log.info("----监听回调事件：{}",eventType);
            CpAbstractHandler abstractHandler = eventHandlerMap.get(eventType);
            if (abstractHandler != null) {
                newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
                        .event(eventType).handler(this.logHandler, abstractHandler).end();
            }
        });

        // 记录所有事件的日志 （异步执行）
        newRouter.rule().handler(this.logHandler).next();

        // 默认
        newRouter.rule().async(false).handler(this.logHandler).end();

        return newRouter;
    }
}
